#pragma once

// Forward declaration 
class Calculator;
namespace Gdiplus
{
	class GraphicsPath;
	class PointF;
	class Graphics;
};

class ContourDot
{
	float mCenterX, mCenterY; // the center of the contour dot

	// sizes of the outer and inner shapes
	float mOuterHalfsize, mMinXi, mMaxXi;

	// tangent vector in forward direction, the square sides are parallel to it
	float mVx, mVy;	

	float mA, mB, mM, mCurvature;
	float mApproximationPrecision, mBrightness, mLineWidth;
	
	// it is the colors at both sides of contour dot, saved as components: 
	// red1, green1, blue1, red2, green2, blue2
	short int mSideColorsComponents[6];

public:
	// constructor for the first dot in a new stroke
	ContourDot(int x, int y);

	bool PlaceAtInitialPosition(Calculator&);
	bool PlaceAtNeighborPosition(Calculator&, bool moveForward);
	void Finalize(Calculator&);
	bool CanBeNeighbor(const ContourDot& inOtherDot) const;

	float GetX() const;
	float GetY() const;
	float GetVx() const;
	float GetVy() const;
	float GetOuterHalfsize() const;
	float GetApproximationPrecision() const;
	float GetBrightness() const;
	float GetLineWidth() const;
	float GetCurvature() const;
	
	float GetMinXi() const;
	float GetMaxXi() const;

	void AddOuterShapeToGraphicsPath(Gdiplus::GraphicsPath& outPath) const;
	void AddInnerShapeToGraphicsPath(Gdiplus::GraphicsPath& outPath,
		float minEta, float maxEta) const;
	void DrawSideColors(Gdiplus::Graphics& outGraphics,
		float minEta, float maxEta) const; 

private:
	bool FitCenterline(Calculator&);
	float ApproachCenterline(Calculator&, bool& outSuccess);
	bool CalculateTangentVector();
	
	// extract all parameters from the calculator
	void UpdateAllParameters(Calculator&);

	// changes position of center in the direction transversal to line of contour.
	void MoveByXi(float xi);
	void MoveByEta(float eta);

	void AddXiCurveToGraphicsPath(Gdiplus::GraphicsPath& outPath,
		float minEta, float maxEta, float constXi) const;
	void AddEtaLineToGraphicsPath(Gdiplus::GraphicsPath& outPath,
		float eta) const;
	inline Gdiplus::PointF MapToPoint(float xi, float eta) const;
	DWORD GetSideColorARGB(int offsetToColor) const;
};

